//
// Test Suite for geos::noding::snapround::HotPixel class.

#include <tut/tut.hpp>
// geos
#include <geos/algorithm/LineIntersector.h>
#include <geos/noding/snapround/HotPixel.h>
#include <geos/geom/Coordinate.h>
#include <geos/geom/Envelope.h>
#include <geos/geom/PrecisionModel.h>
// std
#include <memory>

namespace tut {
//
// Test Group
//

// Common data used by all tests
struct test_hotpixel_data {

    typedef geos::geom::Coordinate Coordinate;
    typedef geos::geom::Envelope Envelope;
    typedef geos::geom::PrecisionModel PrecisionModel;
    typedef geos::algorithm::LineIntersector LineIntersector;
    typedef geos::noding::snapround::HotPixel HotPixel;

    test_hotpixel_data() {}
};

typedef test_group<test_hotpixel_data> group;
typedef group::object object;

group test_hotpixel_group("geos::noding::snapround::HotPixel");

//
// Test Cases
//

// Test with scaleFactor=1
template<>
template<>
void object::test<1>
()
{

    LineIntersector li;
    Coordinate pt(10, 10);
    HotPixel hp(pt, 1, li);

    ensure_equals(hp.getCoordinate(), pt);

    const Envelope& env = hp.getSafeEnvelope();
    ensure_equals(env.toString(), "Env[9.25:10.75,9.25:10.75]");

    Coordinate p0(0, 10);
    Coordinate p1(20, 10);
    ensure("hp.intersects 0 10, 20 10", hp.intersects(p0, p1));

    p1.y = 11; // intersection point within 0.75 distance
    ensure("hp.intersects(0 10, 20 11)", hp.intersects(p0, p1));

    p1.y = 20;
    ensure_not("!hp.intersects(0 10, 20 20)", hp.intersects(p0, p1));

}

// Test with scaleFactor=10
// See http://trac.osgeo.org/geos/ticket/498
template<>
template<>
void object::test<2>
()
{

    LineIntersector li;
    Coordinate pt(10, 10);
    HotPixel hp(pt, 10, li);

    ensure_equals(hp.getCoordinate(), pt);

    const Envelope& env = hp.getSafeEnvelope();
    ensure_equals(env.toString(), "Env[9.925:10.075,9.925:10.075]");

    Coordinate p0(0, 10);
    Coordinate p1(20, 10);
    ensure("hp.intersects 0 10, 20 10", hp.intersects(p0, p1));

    p1.y = 11; // intersection point not within 0.075 distance
    ensure_not("hp.intersects(0 10, 20 11)", hp.intersects(p0, p1));

}

// Test intersects
// See http://trac.osgeo.org/geos/ticket/635
template<>
template<>
void object::test<3>
()
{

    double scale = 1.0;
    Coordinate p1(0, 0);
    Coordinate p2(3, 2);
    Coordinate p3(1, 1);

    PrecisionModel pm(scale);
    LineIntersector li(&pm);
    HotPixel hp(p3, scale, li);

    ensure(hp.intersects(p1, p2));

}

// TODO: test addSnappedNode !


} // namespace tut
